#-------------------------------------------------------------------------------
# Name:        AdwinPro.py
# Purpose:
#
# Author:      Patrick Sanchez
#
# Created:     13/03/2011
# Copyright:   (c) CNRS 2011
#-------------------------------------------------------------------------------
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import sys
import ADwin
#from pylab import *
import numpy as np
import time

DEBUG=True


class AIN_F8_14_revb3:
    def __init__(self,nbpoint=2018,acq_mode=2,srate=2000000,trig_slope=2,gain=3):
        self.nbpoint=nbpoint            #nombre point acquisition
        self.acq_mode=acq_mode          #mode acquisition
        self.srate=srate                #freq. echantillonnage
        self.dt=1.0/self.srate          # calcul periode echantillonnage
        self.trig_slope = trig_slope    # front acquisition
        self.gain=gain                  # gain voie acquisition
        # initialisation
        if not DEBUG:
            self.adw=ADwin.ADwin()
            self.adw.raiseExceptions = 0
        return

    def create(self,nbpoint=2018,acq_mode=2,srate=2000000,trig_slope=2,gain=3):
        self.nbpoint=nbpoint            #nombre point acquisition
        self.acq_mode=acq_mode          #mode acquisition
        self.srate=srate                #freq. echantillonnage
        self.dt=1.0/self.srate          # calcul periode echantillonnage
        self.trig_slope = trig_slope    # front acquisition
        self.gain=gain                  # gain voie acquisition
        self.st=self.srate2sp(self.srate)              # sampling period
        return

    def boot_loader(self,filename):
        if not DEBUG:
            self.filename=filename
            if (os.path.exists(self.filename) and os.path.isfile(self.filename)):
                        self.adw.Boot(filename)
        return

    def load_process(self,filename):
        self.filename=filename
        self.flagOneInstance=0
        if not DEBUG:
            if (os.path.exists(self.filename) and os.path.isfile(self.filename)):
                        self.adw.Load_Process(filename)
        return

    def start_process(self,processnumber=1):
        "lance le process par son numero"
        "le numero est initialise dans Adwin"
        if not DEBUG:
            self.adw.Set_Par(6, 1)
            self.adw.Start_Process(processnumber)# start Process
            while (self.adw.Get_Par(6)==1):
                pass
        return

    def stop_process(self,processnumber):
        "arrete le process par son numero"
        if not DEBUG:
            self.adw.Stop_Process(processnumber)
            while self.adw.Process_Status(processnumber) <> 0:
                pass
        return

    def clear_process(self,processnumber):
        "detruit le process par son numero"
        if not DEBUG:
            self.adw.Clear_Process(processnumber)
        return

    def srate2sp(self,freq):
        "convertion freq. ech en sampling periode pour le module"
        per =  25e-9    # periode pour le processeur T10
        self.dt=1.0/freq
        sp= int(self.dt/per)
        if sp <20:
            print "sampling periode inferieure a 20 !!!"
        return sp

    def set_buffersise(self,size):
        "definition du nombre de point acquisition"
        "transmis par PAR_1"
        if not DEBUG:
            self.adw.Set_Par(1,size)  # taille du buffer acquisition
        return

    def set_acq_mode(self,acqmode):
        "definition du mode acquisition en fonction des voies"
        "transmis par PAR_2"
        "nb voie	mode	max buffe size"
        "1	1	1048575"
        "2	2	524287"
        "3	3	262143"
        "4	3	262143"
        "5	4	131071"
        "6	4	131071"
        "7	4	131071"
        "8	4	131071"
        if not DEBUG:
            self.adw.Set_Par(2,acqmode)
        return

    def calcul_acq_mode(self,nbvoie):
        "calcule le mode acquisition en fonction du nombre de voie"
        "renvoie le mode et la taille max du buufer acquisition"
        tab_mode=[1,2,3,3,4,4,4,4]
        tab_max_size=[1048575,524287,262143,262143,131071,131071,131071,131071]
        tab_process=("acq_1.TA1","acq_2.TA1","acq_3.TA1","acq_3.TA1","acq_4.TA1","acq_4.TA1","acq_4.TA1","acq_4.TA1")
        mode=tab_mode[nbvoie-1]
        max_buffer_size=tab_max_size[nbvoie-1]
        process=tab_process[nbvoie-1]
        return mode,max_buffer_size,process

    def set_sampling_period(self,sp):
        "initialise la periode echantillonnage"
        "en fonction de la frequence echantillonnage"
        if not DEBUG:
            if sp>=20:
                self.adw.Set_Par(3,sp) # sampling periode 20 = 2Mhz
            else:
                print "sampling period too small (20=2MHz)"
        return

    def set_trigger(self,trigmode):
        "initialise les mode de declanchement du trigger"
        "1 : front montant"
        "2: front descendant"
        "3 : sur les deux"
        "transmis par PAR_4"
        val_trig=[1,2,3]
        if not DEBUG:
            if trigmode in val_trig:
                self.adw.Set_Par(4,trigmode)
            else:
                print "mauvaise valeur de trigger, doit etre entre 1 et 3"
        return

    def set_gain(self,gain):
        "initialisation du gain des voies"
        "transmis par PAR_5"
        " mode  	|	measurement range"
        "      0	|	+/- 10 V"
        "      1	|	+/- 5 V"
        "      2	|	+/- 2.5 V"
        "	     3	|	+/- 1.25 V"
        val_gain=[0,1,2,3]
        if not DEBUG:
            if gain in val_gain:
                self.adw.Set_Par(5,gain) # gain
            else:
                print "mauvaise valeur du gain, doit etre compris entre 0 et 3"
        return

    def set_delay(self,delay):
        "initialise le retard acquisition"
        if not DEBUG:
            if delay>1:
                self.adw.Set_Par(8,1) # activation retard
                retard = int(delay*1e4)
                self.adw.Set_Par(7,retard) # delay en ms
            else:
                self.adw.Set_Par(8,0) # desactivation retard   
        return


    def get_parameters(self):
        "test des parametres passes au module acquisition"
        " test PAR_1....PAR_5"
##          buffersize =  PAR_1 ' taille du buffer acquisition <Maxsamples
##          acq_mode =    PAR_2  ' mode acquisition en fonction des voies
##          sampleperiod = PAR_3 ' 'sampling period
##          type_trig =   PAR_4  ' type de trigger
##          gain =        PAR_5       ' gain
        mess="taille  acq. mode sp trig gain\n"
        print mess
        if not DEBUG:
            for i in range(1,6):
                print self.adw.Get_Par(i),
        return

    def get_data(self,nbvoie,nbpoint,gain):
        "transfert des voies acquisition"
        "on donne le gain pour normaliser"
        coef=[20,10,5,2.5]     # coef normalisation
        if not DEBUG:
            N=self.adw.Data_Length(1) # nb. elet. tableau de 8 voie
            d=[]
            buf=[]
            for i in range(1,nbvoie+1,1):
                d.append(self.adw.GetData_Long(i, 1, nbpoint)) # construit la matrice
            buf=np.array(d,dtype=float)
            buf=coef[gain]*(buf -32768)/65536
            print "dans adwin : ",buf.shape
        else:
            buf=np.random.randn(nbvoie,nbpoint)
        return buf

#    def plot_data(self,buf,nbvoie,nbpoint,fs):
#        "affiche les voies acquisition"
#        " buf : buffer des voies acquisition"
#        "nbvoie : nb. de voie acquisition"
#        "nbpoint : taille de la voie en point"
#        "fs : frequence echantillonnage"
#        t=[]
#        dt=1.0/fs
#        t=linspace(0,(nbpoint-1)*dt,nbpoint)
#        figure(1)
#        clf()
#        line=[]
#        for i in range(nbvoie):
#            v=buf[i][0:nbpoint]
#            subplot(nbvoie,1,i+1)
#            plot(t,v)
#            ylabel("Channel "+str(i+1))
#            xlabel("Time [s]")
#        draw()
#        show()
#        return
#
#    def plot_fft(self,buf,nbvoie,nbpoint,fs,npfft,fr):
#        "fft les voies acquisition"
#        " buf : buffer des voies acquisition"
#        "nbvoie : nb. de voie acquisition"
#        "nbpoint : taille de la voie en point"
#        "fs : frequence echantillonnage"
#        "npfft : nb. point de la fft"
#        "fr : frequence de visualisation a droite <Fs/2"
#        f=[]
#        sfft=[]
#        m=[]
#        line=[]
#        df=float(fs/npfft) # pas fft
#        f=arange(0,fs,df)     # axe des freq
#        index=int(npfft*fr/fs)
#        figure(2)
#        clf()
#        for i in range(nbvoie):
#            v=buf[i][0:nbpoint]
#            sfft=fft(v,npfft)
#            m=abs(sfft)/npfft
#            subplot(nbvoie,1,i+1)
#            plot(f[0:index],m[0:index])
#            ylabel("FFT "+str(i+1))
#            xlabel("Freq [Hz]")
#        draw()
#        show()
#        return
#
#    def get_data_fft(self,buf,numvoie,nbpoint,fs,npfft,fr):
#        "fft les voies acquisition"
#        " buf : buffer des voies acquisition"
#        "numvoie : numero de la voie acquisition"
#        "nbpoint : taille de la voie en point"
#        "fs : frequence echantillonnage"
#        "npfft : nb. point de la fft"
#        "fr : frequence de visualisation a droite <Fs/2"
#        "recupere a la fois le signal et la FFT"
#        t=[]
#        dt=1.0/fs
#        t=linspace(0,(nbpoint-1)*dt,nbpoint)
#        df=float(fs)/npfft # pas fft
#        f=arange(0,fs,df)     # axe des freq
#        index=int(npfft*fr/fs)
#        print "numvoie=",numvoie
#        v=buf[numvoie-1][0:nbpoint]
#        sfft=fft(v,npfft)
#        m=abs(sfft)/npfft
#        return t,v,f[0:index],m[0:index]



    def save_binary_file(self,filename,path,buf,header,nbvoie,nbpoint,n,flaginc):
        "sauvegarde dans un fichier binaire"
        "filename : nomdufichier sans extension"
        "buf : tableau des donn?es"
        "nbvoie : nb. voie d acquisition"
        "nbpoint : nb. de point acquisition par voie"
        for i in range(nbvoie):
            header[3]=i
            v=buf[i][0:nbpoint]
            if flaginc:
                nomfic=path+filename+"_v"+"%01d" % i +"_"+"%06d" % n+".dat"
            else:
                nomfic=path+filename+"_v"+"%01d" % i +".dat"
            fd = open(nomfic, 'wb')
            fd.write(header)
            fd.write(v)
            fd.close()
        return


